<template>
    <div class="hotspot-icon h-full">
        <el-form :inline="true" :model="searchform">
            <div class="flex justify-between mb-3">
                <el-space>
                    <el-button size="default" type="primary" :icon="Plus" @click="openEdit('add')">新增</el-button>
                    <el-button type="danger" :icon="Delete" @click="openEdit('add')">删除</el-button>
                </el-space>

                <el-space :size="15">
                    <el-input v-model="searchform.role_name" placeholder="请输入角色名" clearable style="width:200px;"/>
                    <el-button type="primary" @click="getList" :icon="Search">查询</el-button>
                </el-space>
            </div>
        </el-form>
        <div class="table-section grid">
            <el-table border :data="tableData">
                <el-table-column prop="id" label="角色id" width="80px" header-align="center" align="center"/>
                <el-table-column prop="role_name" label="角色名称" header-align="center" align="center"/>
                <el-table-column prop="role_desc" label="角色描述" header-align="center" align="center"/>
                <el-table-column prop="create_time" label="创建时间" header-align="center" align="center"/>
                <el-table-column prop="action" label="操作" fixed="right" width="200px" header-align="center" align="center">
                    <template #default="scope">
                        <el-button type="primary" plain @click="openEdit('update',scope.row)">编辑</el-button>
                        <el-button type="danger" plain>删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </div>
    </div>

    <!--  添加项目弹框  -->
    <el-dialog v-model="editData.visible" :title="editData.title" center :show-close="false" width="30%" top="10vh" :close-on-click-modal="false">
        <div class="dialog-content">
            <div class="edit-form">
                <el-form :model="editData.form" label-width="auto" ref="formRef" :rules="editData.rules">
                    <el-row :gutter="50">
                        <el-col :span="24">
                            <el-form-item label="角色名称" prop="role_name">
                                <el-input v-model="editData.form.role_name" placeholder="请输入角色名称"/>
                            </el-form-item>
                        </el-col>

                        <el-col :span="24">
                            <el-form-item label="角色描述" prop="role_desc">
                                <el-input v-model="editData.form.role_desc" placeholder="请输入角色名称"/>
                            </el-form-item>
                        </el-col>

                        <el-col :span="24">
                            <el-form-item label="菜单权限" prop="perm">
                                <el-checkbox v-model="editData.is_expand_all" label="展开/折叠" @change="expandChange"/>
                                <el-checkbox v-model="editData.is_select_all" label="全选/全不选" @change="selectChange"/>
                            </el-form-item>
                        </el-col>

                        <el-col :span="24">
                            <el-form-item label="" prop="perm" label-width="80">
                                <el-tree
                                    show-checkbox
                                    node-key="id"
                                    :data="editData.treeList"
                                    :props=" { children: 'children',label: 'name'}"
                                    style="max-width: 600px"
                                    :default-expand-all="editData.is_expand_all"
                                    ref="treeRef"
                                />
                            </el-form-item>
                        </el-col>
                    </el-row>
                </el-form>
            </div>
        </div>
        <template #footer>
            <div class="dialog-footer">
                <el-button @click="editData.visible = false">取消</el-button>
                <el-button type="primary" @click="submitForm">确定</el-button>
            </div>
        </template>
    </el-dialog>

</template>
<script setup>
import { ref, reactive, nextTick, onMounted } from 'vue'
import { Delete, Edit, Search, Share, Plus } from '@element-plus/icons-vue'
import roleApi from 'api/model/role.js'

/******************************* 角色的增删改查 *******************************/

const searchform = reactive({ role_name: '' })

// 表格数据
const tableData = ref([])

// 编辑表单
const editData = reactive({
    type: 'add',
    visible: false,
    form: {
        id: '',
        role_name: '',
        role_desc: '',
        menu_ids: '',
    },
    rules: {
        role_name: [
            { required: true, message: '请输入角色名称', trigger: 'blur' },
        ],
    },
    treeList: [],
    is_expand_all: true,
    is_select_all: false,
})

// 表单 ref 对象
const formRef = ref()

// 打开表单窗口
function openEdit (type, item) {
    editData.title = type === 'add' ? '新增角色' : '编辑角色'
    editData.visible = true
    editData.type = type
    nextTick(() => {
        formRef.value.resetFields()
        if (type === 'update') {
            const { id, role_name, role_desc } = item || {}
            editData.form.id = id
            editData.form.role_name = role_name
            editData.form.role_desc = role_desc
            getDetailsById()
        }
    })
}

// 提交表单
const submitForm = async () => {
    // 获取所有选中的节点
    const checkedNodes = treeRef.value.getCheckedKeys()

    // 获取所有半选中的节点
    const halfCheckedNodes = treeRef.value.getHalfCheckedKeys()

    const ids = [...checkedNodes, ...halfCheckedNodes]

    const permissionList = ids.filter(id => menuMap[id].menu_type ===3);

    // 权限id集合
    const permissionIds = permissionList.join(',');

    // 菜单id集合

    editData.form.menu_ids = menu_ids.join(',')

    await formRef.value.validate((valid, fields) => {
        if (valid) {
            editData.type === 'add' ? addItem() : updateItem()
        } else {
            ElMessage.warning('请将表单填写完整')
        }
    })
}

/** 获取表格列表 **/
async function getList () {
    const { code, data = [] } = await roleApi.list.get({
        role_name: searchform.role_name,
    })
    if (code === 0) {
        tableData.value = data
    }
}

/** 新增列表项 **/
async function addItem () {
    const { code, data = [] } = await roleApi.add.post(editData.form)
    if (code === 0) {
        ElMessage.success('新增成功')
        editData.visible = false
        getList()
    }
}

/** 编辑列表项 **/
async function updateItem () {
    const { code, data = [] } = await roleApi.update.post(editData.form)
    if (code === 0) {
        editData.visible = false
        getList()
        ElMessage.success('编辑成功')
    }
}

/** 获取角色详情 **/
async function getDetailsById () {
    console.log(roleApi.details.get, '----------')
    const { code, data = [] } = await roleApi.details.get({
        id: editData.form.id
    })

    if (code === 0) {

        const { menu_ids } = data || {}
        editData.form.menu_ids = menu_ids.split(',')
        nextTick(() => {
            treeRef.value.setCheckedKeys(editData.form.menu_ids)
        })
    }
}

/******************************* 菜单列表的获取处理 *******************************/

import menuApi from 'api/model/menu.js'

// 菜单平铺列表
const menuList = ref([])

// 菜单对象映射
const menuMap = reactive({})

// 菜单树数据
const treeRef = ref()

// 节点展开折叠切换
function expandChange () {
    editData.is_expand_all ? expandAll() : collapseAll()
}

// 全选/全不选切换
function selectChange () {
    editData.is_select_all ? selectAll() : unselectAll()
}

/**
 *  获取类型列表
 */
async function getMenuList () {
    const { code, data = [] } = await menuApi.list.get()
    if (code === 0) {
        menuList.value = data
        menuList.value.forEach(item => {
            menuMap[item.id] = item
        })
        // 将扁平化数组转换为嵌套结构
        editData.treeList = convertToTree(data)
    }
}

/**
 * 通过parent_id获取树形结构
 * @param data
 * @returns {*}
 */
function convertToTree (data) {
    // 创建一个映射表，方便快速查找节点
    const map = {}
    data.forEach(item => {
        map[item.id] = { ...item, children: [] }
    })

    // 构建树结构
    const tree = []
    data.forEach(item => {
        if (item.parent_id === 0) {
            // 顶级节点
            tree.push(map[item.id])
        } else {
            // 子节点，添加到父节点的 children 中
            const parent = map[item.parent_id]
            if (parent) {
                parent.children.push(map[item.id])
            }
        }
    })

    return tree
}

// 展开全部节点
const expandAll = () => {
    const nodes = treeRef.value?.store.nodesMap
    for (let node in nodes) {
        nodes[node].expanded = true
    }
}

// 折叠全部节点
const collapseAll = () => {
    const nodes = treeRef.value?.store.nodesMap
    for (let node in nodes) {
        nodes[node].expanded = false
    }
}

// 全选
const selectAll = () => {
    const allKeys = getAllKeys(editData.treeList)
    treeRef.value?.setCheckedKeys(allKeys)
    editData.is_select_all = true
}

// 全不选
const unselectAll = () => {
    treeRef.value?.setCheckedKeys([])
    editData.is_select_all = false
}

// 获取所有节点的key
const getAllKeys = (data) => {
    let keys = []
    data.forEach(item => {
        keys.push(item.id)
        if (item.children && item.children.length > 0) {
            keys = keys.concat(getAllKeys(item.children))
        }
    })
    return keys
}

onMounted(() => {
    getList()
    getMenuList()
})

</script>


<style lang="less">

</style>